package com.twu.biblioteca.model;

import com.twu.biblioteca.exceptions.AssetUnavailableException;
import com.twu.biblioteca.exceptions.BookDoesntBelongToLibraryException;
import com.twu.biblioteca.exceptions.BookNotAvailableException;
import com.twu.biblioteca.exceptions.MovieDoesNotBelongToLibraryException;

import java.util.*;

/**
 * Created by davecroman on 11/09/2014.
 */
public class Library {

    private HashMap<Integer, Book> books;
    private HashMap<Integer, Movie> movies;
    private Integer idHead;

    public Library(){
        this.books = new HashMap<Integer, Book>();
        this.movies = new HashMap<Integer, Movie>();
        idHead = 0;
    }

    public Map<Integer,Book> getAllBooks(){
        return Collections.unmodifiableMap(books);
    }

    public Map<Integer,Movie> getAllMovies() {
        return Collections.unmodifiableMap(movies);
    }

    public void supplyBooks(Set<Book> booksToAdd){
        for( Book book : booksToAdd ){
            books.put(book.getId(),book);
        }
    }

    public void supplyMovies(Set<Movie> moviesToAdd) {
        for( Movie movie : moviesToAdd ){
            movies.put(movie.getId(), movie);
        }
    }

    public void checkOut(Book bookToBorrow, UserAccount userAccount) throws BookNotAvailableException {
        if( bookToBorrow.isAvailable() ){
            bookToBorrow.borrow(userAccount);
        }else{
            throw new BookNotAvailableException();
        }
    }

    public void returnBook(Book book) throws BookDoesntBelongToLibraryException {
        if( books.containsValue(book) ){
            book.returnBack();
        }else{
            throw new BookDoesntBelongToLibraryException();
        }
    }

    public void returnMovie(Movie movie) throws MovieDoesNotBelongToLibraryException {
        if( movies.containsValue(movie) ){
            movie.returnBack();
        }else{
            throw new MovieDoesNotBelongToLibraryException();
        }
    }

    public void checkOut(Integer bookId, UserAccount userAccount) throws BookDoesntBelongToLibraryException, BookNotAvailableException {
        final Book book = books.get(bookId);

        if( book == null ){
            throw new BookDoesntBelongToLibraryException();
        }

        checkOut(book, userAccount);
    }

    public void checkOutMovie(Integer movieId, UserAccount user) throws MovieDoesNotBelongToLibraryException, AssetUnavailableException {
        final Movie movie = movies.get(movieId);

        if(movie == null){
            throw new MovieDoesNotBelongToLibraryException();
        }

        borrowAsset(movie, user);
    }

    private void borrowAsset(BorrowableAsset asset, UserAccount user) throws AssetUnavailableException {
        if( asset.isAvailable() ){
            asset.borrow(user);
        }else {
            throw new AssetUnavailableException();
        }
    }

    public Book getBook(Integer id) {
        return books.get(id);
    }

    public Movie getMovie(Integer id) {
        return movies.get(id);
    }
}
